package com.dyrj.ysk.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dcits.openapi.utils.DcRSA;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * JSON工具
 *
 * OpenApi提供,非本人开发
 */
public class JSONSignUtil {

    public static boolean check(JSONObject json, String sign, String pubKey) throws Exception {
        String content = getSign(json);
        if (content == null) {
            return false;
        }
        return DcRSA.checkV1(content, sign, pubKey);
    }


    public static String sign(JSONObject json, String privateKey) {
        String content = getSign(json);
        if (content == null) {
            return null;
        }
        try {
            return DcRSA.signV1(content, privateKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String getSign(JSONObject jsonObj) {
        Map<String, String> map = new HashMap<>();
        getNeedMap(jsonObj, map);
        Map<String, String> resultMap = sortMapByKey(map);
        if (resultMap != null) {
            String stringA = "";
            for (Map.Entry<String, String> entry : resultMap.entrySet()) {
                String value = entry.getValue();
                if (value != null && !"".equals(value)) {
                    stringA = stringA.concat(entry.getKey()).concat("=").concat(value).concat("&");
                }
            }
            return stringA;
        }
        return null;
    }

    private static Map<String, String> sortMapByKey(Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, String> sortMap = new TreeMap<>(String::compareTo);
        sortMap.putAll(map);
        return sortMap;
    }

    private static void getNeedMap(JSONObject jsonObj, Map<String, String> map) {
        for (String key : jsonObj.keySet()) {
            Object object = jsonObj.get(key);
            if (object instanceof JSONObject) {
                JSONObject obj = (JSONObject) object;
                getNeedMap(key, obj, map);
            } else if (object instanceof JSONArray) {
                JSONArray jsonArray = (JSONArray) object;
                for (Object arrayObject : jsonArray) {
                    if (arrayObject instanceof String) {
                        map.put((String) arrayObject, (String) arrayObject);
                    } else {
                        getNeedMap(key, (JSONObject) arrayObject, map);
                    }
                }
            } else if (object instanceof String) {
                map.put(key, (String) object);
            }
        }
    }

    private static void getNeedMap(String parent, JSONObject jsonObj, Map<String, String> map) {
        for (String key : jsonObj.keySet()) {
            Object object = jsonObj.get(key);
            if (object instanceof JSONObject) {
                JSONObject Obj = (JSONObject) object;
                getNeedMap(parent.concat(key), Obj, map);
            } else if (object instanceof JSONArray) {
                JSONArray jsonArray = (JSONArray) object;
                for (Object arrayObject : jsonArray) {
                    if (arrayObject instanceof String) {
                        map.put(parent.concat((String) arrayObject), (String) arrayObject);
                    } else {
                        getNeedMap(parent.concat(key), (JSONObject) arrayObject, map);
                    }
                }
            } else if (object instanceof String) {
                map.put(parent.concat(key), (String) object);
            }
        }
    }

}
